#ifndef AVALON_TASKWRITER_HPP
#define AVALON_TASKWRITER_HPP
#include <vector>
#include "Avalon/Base/Handle.hpp"
#include "Avalon/IO/Buffer.hpp"
#include "Avalon/IO/Writer.hpp"
#include "Avalon/Threading/ThreadPool.hpp"

namespace Avalon {
namespace IO {

  /*! \class TaskWriter
   *  \brief Performs write operations within a ThreadPool.
   */
  class TaskWriter : public Writer {
    public:

      //! Constructs a TaskWriter.
      /*!
        \param destination The destination to write to.
        \param threadPool The ThreadPool to use for write operations.
      */
      TaskWriter(Carry<Writer> destination, Threading::ThreadPool& threadPool);

      virtual ~TaskWriter();

      virtual void Write(const void* data, int size,
        Out<Threading::Async<void> > result);

      virtual void Write(const Buffer& data,
        Out<Threading::Async<void> > result);

    private:
      struct PendingWrite {
        const void* m_data;
        int m_size;
        Buffer m_buffer;
        Threading::Async<void>* m_result;

        PendingWrite(const void* data, int size,
          Threading::Async<void>* result);

        PendingWrite(const Buffer& buffer, Threading::Async<void>* result);
      };
      boost::mutex m_mutex;
      Handle<Writer> m_destination;
      Threading::ThreadPool& m_threadPool;
      std::vector<PendingWrite> m_pendingWrites;
  };
}
}

#endif // AVALON_TASKWRITER_HPP
